/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.SOP;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.application.FacesMessage;
import merlion.common.util.exception.NotExistException;
import merlion.crm.slcm.entity.Customer;
import merlion.crm.slcm.entity.MemberDiscountGroup;
import merlion.crm.slcm.entity.OrderDiscountGroup;
import merlion.crm.slcm.entity.SalesLead;
import merlion.crm.slcm.session.SLCSessionBeanLocal;
import merlion.crm.sopm.entity.ItemLine;
import merlion.crm.sopm.entity.SalesInquiry;
import merlion.crm.sopm.session.SOPSessionBeanLocal;
import merlion.mrp.ppm.entity.Product;

/**
 *
 * @author Yuwei nd Hong
 */
@ManagedBean(name = "slManagerBean")
@ViewScoped
public class SalesInquiryManagerBean {

    public static final String SI = "SI";
    public static final String RESULT1 = "RESULT2";
    public static final String CUR = "CUR";
    @EJB
    private SOPSessionBeanLocal sOPSessionBean;
    @EJB
    private SLCSessionBeanLocal sLCSessionBean;
    private SalesInquiry salesInquiry;
    private SalesLead sl;
    private Customer customer;
    private String rfiNumber;
    private String siNumber;
    private OrderDiscountGroup orderDiscountGroup;
    private String customerExecutiveId;
    private String currency;
    private Double memberDiscount;
    private Double orderDiscount;
    private ItemLine il;
    private ItemLine selectedItemLine;
    private Double itemSubtotal;
    private Double subtotal;
    private Double total;
    private String result;
    private String errorMsg;
    private Collection<Long> orderQtys = new ArrayList<Long>();
    private Collection<OrderDiscountGroup> orderDiscountGroups = new ArrayList<OrderDiscountGroup>();
    private Collection<Double> subtotals = new ArrayList<Double>();
    private String statusMessage;
    private static final SimpleDateFormat formatter = new SimpleDateFormat("MMMMM dd, yyyy");
    private Boolean updateMode;

    /** Creates a new instance of SalesInquiryManagerBean */
    public SalesInquiryManagerBean() {
        this.salesInquiry = new SalesInquiry();
        this.total = 0.0;
        sl = new SalesLead();
       
    }

    ////////////////////////////////ItemLine Operation//////////////////////////
    @PostConstruct
    public void init() {
        SalesInquiry sl = (SalesInquiry) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("SI");
        result = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("RESULT1");
        if (sl != null) {
            salesInquiry = sl;
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("SI");
        } else {
            resetSalesInquiry();
        }
    }

    private void resetSalesInquiry() {

        salesInquiry = new SalesInquiry();
        salesInquiry.setSiNumber(sOPSessionBean.generateSalesInquiryId());

        //Add itemline for all products
        Collection<Product> products = sLCSessionBean.getAllProduct();
        for (Product pd : products) {
            il = new ItemLine();
            //il.setReservation(null);
            il.setProduct(pd);
            salesInquiry.getOrderItems().add(il);
        }
    }

    private void createNewItemLine() {

        //Add itemline for all products
        Collection<Product> products = sLCSessionBean.getAllProduct();
        for (Product pd : products) {
            il = new ItemLine();
            //il.setWarehouse(null);
            il.setProduct(pd);
            salesInquiry.getOrderItems().add(il);
        }
    }

    public void updateItemLine() {

        for (ItemLine il1 : salesInquiry.getOrderItems()) {
            if (il1.equals(selectedItemLine)) {
                //Swap
                il1 = selectedItemLine;
            }
        }
    }

    public void reset() {
        createNewItemLine();
    }

    ////////////////////////////Calculation/////////////////////////////////////
    public String closeSalesInquiry() {
        setResult("Sales Inquiry " + salesInquiry.getSiNumber() + " closed.");
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("RESULT1", result);
        return "viewSalesInquiryStatus?faces-redirect=true";
    }
    
    public String populateSalesInquiry() {

        for (ItemLine il1 : salesInquiry.getOrderItems()) {
            if (salesInquiry.getSalesLead().getCategory().equals("DirectSale")) {
                if (il1.getQtyOrderedCase() < 10 && il1.getQtyOrderedCase() != 0) {
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, "Minimum order amount for direct sale customers: 10 cases", "Minimum order amount for direct sale customers: 10 cases"));
                    return null;
                }
            } else {//for whole sale customers
                if (il1.getQtyOrderedCase() < 50 && il1.getQtyOrderedCase() != 0) {
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, "Minimum order amount for whole sale customers: 50 cases", "Minimum order amount for whole sale customers: 50 cases"));
                    return null;
                }
            }
        }
        int count = 0;
        for (ItemLine il2 : salesInquiry.getOrderItems()) {
            if (il2.getQtyOrderedCase() == 0) {
                count++;
            }
        }
        if (count >= 4) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please fill in the form", "Please fill in th form"));
            return null;
        }

        //Calculate
        this.calculateSubtotals();

        // Sales inquiry
        if (salesInquiry.getComments() == null || salesInquiry.getComments().equals("")) {
            salesInquiry.setComments("No additonal comments from clients.");
        }

        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(SI, salesInquiry);
        return "createSalesInquiryConfirm?faces-redirect=true";
    }

    public String recalculateSalesInquiry() {
        salesInquiry.setSiNumber(salesInquiry.getSiNumber());
        this.calculateSubtotals();
        for (ItemLine il1 : salesInquiry.getOrderItems()) {
            if (salesInquiry.getSalesLead().getCategory().equals("DirectSale")) {
                if (il1.getQtyOrderedCase() < 10 && il1.getQtyOrderedCase() != 0) {
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, "Minimum order amount for direct sale customers: 10 cases", "Minimum order amount for direct sale customers: 10 cases"));
                    return null;
                }
            } else {//for whole sale customers
                if (il1.getQtyOrderedCase() < 50 && il1.getQtyOrderedCase() != 0) {
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, "Minimum order amount for whole sale customers: 50 cases", "Minimum order amount for whole sale customers: 50 cases"));
                    return null;
                }
            }
        }
        int count = 0;
        for (ItemLine il2 : salesInquiry.getOrderItems()) {
            if (il2.getQtyOrderedCase() == 0) {
                count++;
            }
        }
        if (count >= 4) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please fill in the form", "Please fill in th form"));
            return null;
        }
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(SI, salesInquiry);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(CUR, currency);
        return "viewSalesInquiryEditConfirm?faces-redirect=true";

    }

    private void calculateSubtotals() {

        try {
            this.setSl(sLCSessionBean.getSalesLeadByClientId(salesInquiry.getSalesLead().getClientId()));
            salesInquiry.setSalesLead(getSl());
        } catch (NotExistException ex) {
//            return ex.getMessage();
        }

        if (salesInquiry.getSalesLead() instanceof Customer) {
            try {
                Customer c1 = sLCSessionBean.getCustomerByClientId(salesInquiry.getSalesLead().getClientId());

                //Get Member Discount
                MemberDiscountGroup memberDiscountGroup = sLCSessionBean.getCustomerMemberDiscountGroup(c1);
                memberDiscount = memberDiscountGroup.getMemberDiscount();
            } catch (Exception e) {
                System.out.println("Exception: " + e.getMessage());
            }
        } else {
            System.out.println("Setting member discount to 0");
            memberDiscount = 0.0;
        }
        double md = memberDiscount;
        double odAmount = (double) 0;
        double mdAmount = (double) 0;
        double sdAmount = (double) 0;
        double originalPrice = (double) 0;
        double subtotalSum = 0.0;
        ArrayList<ItemLine> totalItemLines = new ArrayList<ItemLine>(salesInquiry.getOrderItems());
        for (int i = 0; i < totalItemLines.size(); i++) {
            ItemLine il = totalItemLines.get(i);
            double quantityBar;
            if (il.getProduct().getProductType().contains("Classic")) {
                quantityBar = (double) il.getQtyOrderedCase() * 240;
            } else {
                quantityBar = (double) il.getQtyOrderedCase() * 200;
            }
            il.setQtyOrderedBar(new Double(quantityBar).longValue());
            orderDiscountGroup = sLCSessionBean.getOrderDiscountGroup(il);
            il.setOrderDiscount(orderDiscountGroup.getOrderDiscount());
            il.setMemberDiscount(memberDiscount);

            //Calculate Subtotal
            if (salesInquiry.getSalesLead().getCategory().equals("DirectSale")) {
                    if (il.getProduct().getProductType().contains("Classic")) {
                        il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getDsUnitPrice() * 240));
                        il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getDsUnitPrice() / 1.2 * 240));
                    } else {
                        il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getDsUnitPrice() * 200));
                        il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getDsUnitPrice() / 1.2 * 200));
                    }
                } else { //WholeSale clients
                    if (il.getProduct().getProductType().contains("Classic")) {
                        il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getWsUnitPrice() * 240));
                        il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getWsUnitPrice() / 1.2 * 240));
                    } else {
                        il.setUnitPriceSGD(roundFourDecimals(il.getProduct().getWsUnitPrice() * 200));
                        il.setUnitPriceUSD(roundFourDecimals(il.getProduct().getWsUnitPrice() / 1.2 * 200));
                    }
                }
             double unitPrice;
                if (salesInquiry.getCurrency() == Boolean.TRUE) {
                    //SGD
                    if (il.getProduct().getProductType().contains("Classic")) {
                        unitPrice = il.getUnitPriceSGD() / 240;
                    } else {
                        unitPrice = il.getUnitPriceSGD() / 200;
                    }
                } else {
                    //USD
                    if (il.getProduct().getProductType().contains("Classic")) {
                        unitPrice = il.getUnitPriceUSD() / 240;
                    } else {
                        unitPrice = il.getUnitPriceUSD() / 200;
                    }

                }
            double od = (double) il.getOrderDiscount();
            double sd = (double) il.getSpecialDiscount();
            itemSubtotal = (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) 1 - (double) md) * ((double) 1 - (double) sd);
            originalPrice = originalPrice + (double) quantityBar * (double) unitPrice;
            odAmount = odAmount + (double) quantityBar * (double) unitPrice * (double) od;
            mdAmount = mdAmount + (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) md);
            sdAmount = sdAmount + (double) quantityBar * (double) unitPrice * ((double) 1.0 - (double) od) * ((double) 1 - (double) md) * (double) sd;
            //Rounding
            itemSubtotal = roundFourDecimals(itemSubtotal);
            il.setSubTotal(itemSubtotal);
            subtotals.add(itemSubtotal);
            subtotalSum = subtotalSum + itemSubtotal;
            totalItemLines.set(i, il);
        }
        salesInquiry.setSubtotal(originalPrice);
        salesInquiry.setMemberDiscount(mdAmount);
        salesInquiry.setOrderDiscount(odAmount);
        salesInquiry.setTotal(subtotalSum);
        
    }

////////////////////////////////////Format//////////////////////////////////////
    private double roundTwoDecimals(double d) {
        DecimalFormat twoDForm = new DecimalFormat("#.##");
        return Double.valueOf(twoDForm.format(d));
    }

    private double roundFourDecimals(double d) {
        DecimalFormat fourDForm = new DecimalFormat("#.####");
        return Double.valueOf(fourDForm.format(d));
    }

    private String convertToDateFormat(Timestamp timeStamp) {
        return formatter.format((java.util.Date) timeStamp);
    }

    public String confirmSalesInquiry() {
        try {
            salesInquiry.setSalesLead(sLCSessionBean.getSalesLeadByClientId(salesInquiry.getSalesLead().getClientId()));
        } catch (NotExistException ex) {
        }
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(RESULT1, result);
        return "viewSalesInquiryStatus?faces-redirect=true";
    }

    public String persistSalesInquiry() {
        SalesInquiry si = sOPSessionBean.saveSalesInquiry(salesInquiry);
        if (si != null) {
            System.out.println("sales inquiry " + si.getSiNumber() + " saved successfully");
            result = "Sales Inquiry of ID " + si.getId() + " , Sales Inquiry Number " + si.getSiNumber() + " saved successfully.";
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(RESULT1, result);
            return "viewSalesInquiryStatus?faces-redirect=true";
        } else {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Sales Inquiry didn't saved successfully", "Sales Inquiry didn't saved successfully"));
            return null;
        }
    }

    public String cancelSalesInquiry() {
        //FacesContext.getCurrentInstance().addMessage(null,
        // new FacesMessage(FacesMessage.SEVERITY_ERROR, "Purchase Order creation cancelled", "Purchase Order creation cancelled"));
        result = "Sales Inquiry cancelled and has not been saved.";
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(RESULT1, result);
        return "viewSalesInquiryStatus?faces-redirect=true";
    }

    public String displaySalesInquiry() {
        try {
            salesInquiry = sOPSessionBean.getSalesInquiryById(getSiNumber());
        } catch (NotExistException e) {
            //TO DO: Handle exceptions
        }
        sl = salesInquiry.getSalesLead();
        boolean currencyBoolean = salesInquiry.getCurrency();
        if (currencyBoolean == Boolean.TRUE) {
            currency = "SGD";
        } else {
            currency = "USD";
        }
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(SI, salesInquiry);
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(CUR, currency);
        return "viewSalesInquiryDisplay?faces-redirect=true";
    }

    public String updateSalesInquiry() {
   
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(SI, salesInquiry);
        return "viewSalesInquiryEdit?faces-redirect=true";
    }

    public String cancelEditSI() {
        System.out.println("ERROR HERE: cancelEditSI");
        result = "Sales Inquiry " + salesInquiry.getSiNumber() + " cancel edit.";
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(RESULT1, result);
        return "viewSalesInquiryStatus?faces-redirect=true";
    }

    ////////////////////////GETTER AND SETTOR///////////////////////////////////
    public String getCustomerExecutiveId() {
        return customerExecutiveId;
    }

    public void setCustomerExecutiveId(String customerExecutiveId) {
        this.customerExecutiveId = customerExecutiveId;
    }

    public SLCSessionBeanLocal getsLCSessionBean() {
        return sLCSessionBean;
    }

    public void setsLCSessionBean(SLCSessionBeanLocal sLCSessionBean) {
        this.sLCSessionBean = sLCSessionBean;
    }

    public SOPSessionBeanLocal getsOPSessionBean() {
        return sOPSessionBean;
    }

    public void setsOPSessionBean(SOPSessionBeanLocal sOPSessionBean) {
        this.sOPSessionBean = sOPSessionBean;
    }

    public SalesInquiry getSalesInquiry() {
        SalesInquiry si = (SalesInquiry) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(SI);

        if (si != null) {
            salesInquiry = si;
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(SI);
        } else {
            System.out.println("sales inquiry is null" + si);
        }
        return salesInquiry;
    }

    public void setSalesInquiry(SalesInquiry salesInquiry) {
        this.salesInquiry = salesInquiry;
        this.siNumber = salesInquiry.getSiNumber();
    }

    /**
     * @return the rfiNumber
     */
    public String getRfiNumber() {
        return rfiNumber;
    }

    /**
     * @param rfiNumber the rfiNumber to set
     */
    public void setRfiNumber(String rfiNumber) {
        this.rfiNumber = rfiNumber;
    }

    /**
     * @return the customer
     */
    public Customer getCustomer() {
        return customer;
    }

    /**
     * @param customer the customer to set
     */
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    /**
     * @return the memberDiscount
     */
    public Double getMemberDiscount() {
        return memberDiscount;
    }

    /**
     * @param memberDiscount the memberDiscount to set
     */
    public void setMemberDiscount(Double memberDiscount) {
        this.memberDiscount = memberDiscount;
    }

    /**
     * @return the orderDiscount
     */
    public Double getOrderDiscount() {
        return orderDiscount;
    }

    /**
     * @param orderDiscount the orderDiscount to set
     */
    public void setOrderDiscount(Double orderDiscount) {
        this.orderDiscount = orderDiscount;
    }

    /**
     * @return the subtotal
     */
    public Double getSubtotal() {
        return subtotal;
    }

    /**
     * @param subtotal the subtotal to set
     */
    public void setSubtotal(Double subtotal) {
        this.subtotal = subtotal;
    }

    /**
     * @return the total
     */
    public Double getTotal() {
        return total;
    }

    /**
     * @param total the total to set
     */
    public void setTotal(Double total) {
        this.total = total;
    }

    /**
     * @return the orderQtys
     */
    public Collection<Long> getOrderQtys() {
        return orderQtys;
    }

    /**
     * @param orderQtys the orderQtys to set
     */
    public void setOrderQtys(Collection<Long> orderQtys) {
        this.orderQtys = orderQtys;
    }

    /**
     * @return the orderDiscountGroups
     */
    public Collection<OrderDiscountGroup> getOrderDiscountGroups() {
        return orderDiscountGroups;
    }

    /**
     * @param orderDiscountGroups the orderDiscountGroups to set
     */
    public void setOrderDiscountGroups(Collection<OrderDiscountGroup> orderDiscountGroups) {
        this.orderDiscountGroups = orderDiscountGroups;
    }

    /**
     * @return the subtotals
     */
    public Collection<Double> getSubtotals() {
        return subtotals;
    }

    /**
     * @param subtotals the subtotals to set
     */
    public void setSubtotals(Collection<Double> subtotals) {
        this.subtotals = subtotals;
    }

    /**
     * @return the statusMessage
     */
    public String getStatusMessage() {
        return statusMessage;
    }

    /**
     * @param statusMessage the statusMessage to set
     */
    public void setStatusMessage(String statusMessage) {
        this.statusMessage = statusMessage;
    }

    public SalesLead getSl() {
        return sl;
    }

    public void setSl(SalesLead sl) {
        this.sl = sl;
    }

    /**
     * @return the errorMsg
     */
    public String getErrorMsg() {
        return errorMsg;
    }

    /**
     * @param errorMsg the errorMsg to set
     */
    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    /**
     * @return the updateMode
     */
    public Boolean getUpdateMode() {
        return updateMode;
    }

    /**
     * @param updateMode the updateMode to set
     */
    public void setUpdateMode(Boolean updateMode) {
        this.updateMode = updateMode;
    }

    /**
     * @return the result
     */
    public String getResult() {
        String r = (String) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(RESULT1);
        System.out.println("debugging" + r);
        if (r != null) {
            result = r;
            FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(RESULT1);
        }
        return result;
    }

    /**
     * @param result the result to set
     */
    public void setResult(String result) {
        this.result = result;
    }

    public String getSiNumber() {
        return siNumber;
    }

    public void setSiNumber(String siNumber) {
        this.siNumber = siNumber;
    }

    public ItemLine getIl() {
        return il;
    }

    public void setIl(ItemLine il) {
        this.il = il;
    }

    public Double getItemSubtotal() {
        return itemSubtotal;
    }

    public void setItemSubtotal(Double itemSubtotal) {
        this.itemSubtotal = itemSubtotal;
    }

    public OrderDiscountGroup getOrderDiscountGroup() {
        return orderDiscountGroup;
    }

    public void setOrderDiscountGroup(OrderDiscountGroup orderDiscountGroup) {
        this.orderDiscountGroup = orderDiscountGroup;
    }

    public ItemLine getSelectedItemLine() {
        return selectedItemLine;
    }

    public void setSelectedItemLine(ItemLine selectedItemLine) {
        this.selectedItemLine = selectedItemLine;
    }
    
}
